
//
// Global.m   Part of Cassandra
//
// Copyright (c) 1989, 1990, 1991 by Jiro Nakamura
// All rights reserved
//
// RCS Information
// Revision Number->	$Revision: 2.14 $
// Last Revised->	$Date: 91/12/20 15:36:33 $
//
static char rcsid[] = "$Id: Global.m,v 2.14 91/12/20 15:36:33 jiro Exp Locker: jiro $";

#import "Global.h"
#import <stdio.h>
#import <libc.h>
#import <strings.h>
#import <stdlib.h> 			// for atoi() 
#import <sys/file.h>			// for access()
#import	<math.h>			// for log10()
#import <appkit/Button.h>
#import <appkit/Window.h>
#import <appkit/Form.h>
#import <appkit/Application.h>  	// for NXHomeDirectory()
#import <defaults/defaults.h>		// for NXWriteDefault() 
#import <appkit/Panel.h>		// for NXRunAlertPanel()
#import <appkit/OpenPanel.h>		// for OpenPanel
#import <appkit/publicWraps.h>  /* for NXBeep( ) 		*/

#import "cass.h"
#import "calendar.h"
#import "Event.h"
#import "Cassandra.h"
const char *const alarmExtensions[] = ALARMEXTENSIONS;

BOOL getDefaultValue(char *defaultName, BOOL dflt)
{
	char *str;
	str = (char *) NXGetDefaultValue(PROGNAME, defaultName);
	return(	(!str || (str[0] == (dflt?'Y':'N')) ||
		(str[0] == (dflt?'y':'n'))) ? dflt : !dflt) ;
}
	
@implementation Global
+ initialize
{
	// From NeXT 0.9 Concepts manual, chap. 9, pp.13-16
	static NXDefaultsVector myDefaults =
		{
			{ DEFAULTALARMSOUND,		ALARMSOUND},
			{ DEFAULTALARMVOLUME,		"-1.0"},
			{ DEFAULTAUTOLAUNCHED,		"No" },
			{ DEFAULTCLOCKFACENUMBER,	"12"},
			{ DEFAULTCLOCKTYPE,		"0"},
			{ DEFAULTCOMPRESSEVENTS,	"Yes"},
			{ DEFAULTDIRECTORY,		NULL},
			{ DEFAULTEVENTLOGFRAME,		"x600y10w425h200"},
			{ DEFAULTEVENTLOGONLAUNCH,	"No"},
			{ DEFAULTFONTNAME,		FONTNAME},
			{ DEFAULTFONTSIZE,		FONTSIZEQ},
			{ DEFAULTGURU,			"No"},
			{ DEFAULTHIDEONLAUNCH		"No"},
			{ DEFAULTHIGHPRIORITY,		"90"},
			{ DEFAULTLOWPRIORITY,		"10"},
			{ DEFAULTMILITARYTIME,		"No"},
			{ DEFAULTNOTEPADFRAME,		"x75y10w425h200"},
			{ DEFAULTNOTEPADONLAUNCH,	"No"},
			{ DEFAULTOVERVIEWFRAME,		"x215y280w530h490"},
			{ DEFAULTOVERVIEWONLAUNCH, 	"Yes"},
			{ DEFAULTPLAYALARM,		"Yes"},
			{ DEFAULTSAVESCREEN,		"No"},
			{ DEFAULTSCREENSAVER,		SCREENSAVER},
			{ DEFAULTSHOWSECONDS, 		"Yes"},
			{ DEFAULTSHOWDATE, 		"No"},
			{ DEFAULTSOURCELOGINONLAUNCH,	"No"},
			{ DEFAULTTODAYSHOWTIME,		"No"},
			{ DEFAULTTODAYONLAUNCH,		"Yes"},
			{ DEFAULTTODAYFRAME,		"x5y280w200h265"},
			{ DEFAULTWEEKFRAME,		"x78y15w870h165"},
			{ NULL}
		};
	
	#ifdef DEBUG
		fprintf(stderr, "Global being initialized\n");
	#endif

	NXRegisterDefaults( PROGNAME, myDefaults);
	return self;
}

- load:sender
{
	const char *str;
 	char tmp[128];
	
	#ifdef DEBUG
	int count;
	for( count = 0; count < NXArgc; count ++ )
		{
		fprintf(stderr,"%s: NXArgv[%d] = <%s>\n", PROGNAME, count,
			NXArgv[count]);
		}
	#endif
	
  
	str = NXGetDefaultValue(PROGNAME, DEFAULTDIRECTORY);
	if( str == NULL)
		{
		sprintf(directory, "%s%s", NXHomeDirectory(), DIRECTORY);
		NXWriteDefault( PROGNAME, DEFAULTDIRECTORY, directory);
		}
	else
		strcpy(directory, str);

	sprintf( eventFile, "%s%s", directory, 		EVENTFILE);
	sprintf( eventLogFile, "%s%s", directory, 	EVENTLOGFILE);
	sprintf( notepadFile, "%s%s", directory, 	NOTEPADFILE);
	sprintf( sourceLoginFile, "%s%s", directory, 	SOURCELOGINFILE);
	sprintf( sourceLogoutFile, "%s%s", directory, 	SOURCELOGOUTFILE);
	
	strcpy(tmp, directory);
		
	if( *(tmp+ strlen(tmp)-1) == '/')
		* (tmp+ strlen(tmp) -1) = '\0';
	
	if( access( tmp, X_OK) == -1)	// If it doesn't exist
		{
		if( mkdir(tmp, 0700) == -1)		
			{
			char error[180];
			sprintf(error, "I couldn't create the working "
					"directory <%s>", tmp);
			NXRunAlertPanel("Fatal Error", error, "Exit", 
					NULL,NULL);
			exit(1);
			}
		}

	// Read the defaults and store them
	autoLaunched	= getDefaultValue(DEFAULTAUTOLAUNCHED, NO);
	compressEvents	= getDefaultValue(DEFAULTCOMPRESSEVENTS, YES);
	eventLogOnLaunch= getDefaultValue(DEFAULTEVENTLOGONLAUNCH, YES);
	guru 		= getDefaultValue(DEFAULTGURU, 		NO);
	hideOnLaunch 	= getDefaultValue(DEFAULTHIDEONLAUNCH,	NO);
	militaryTime	= getDefaultValue(DEFAULTMILITARYTIME,	NO);
	notepadOnLaunch = getDefaultValue(DEFAULTNOTEPADONLAUNCH, YES);
	overviewOnLaunch= getDefaultValue(DEFAULTOVERVIEWONLAUNCH, YES);
	playAlarm	= getDefaultValue(DEFAULTPLAYALARM,	YES);
	saveScreen	= getDefaultValue(DEFAULTSAVESCREEN, 	NO);
	showSeconds	= getDefaultValue(DEFAULTSHOWSECONDS, 	YES);
	showDate	= getDefaultValue(DEFAULTSHOWDATE,	YES); 
	sourceLoginOnLaunch	
			= getDefaultValue(DEFAULTSOURCELOGINONLAUNCH,	NO);
	todayOnLaunch	= getDefaultValue(DEFAULTTODAYONLAUNCH,	YES);
	todayShowTime	= getDefaultValue(DEFAULTTODAYSHOWTIME, NO);
	weekOnLaunch	= getDefaultValue(DEFAULTWEEKONLAUNCH, 	NO);
	
	// Read the Overview window's frame size 
	str = NXGetDefaultValue(PROGNAME, DEFAULTOVERVIEWFRAME);
	sscanf(str, "x%fy%fw%fh%f",  
		&overviewFrame.origin.x, &overviewFrame.origin.y, 
		&overviewFrame.size.width, &overviewFrame.size.height);
	
	// Read the EventLog window's frame size 
	str = NXGetDefaultValue(PROGNAME, DEFAULTEVENTLOGFRAME);
	sscanf(str, "x%fy%fw%fh%f",  
		&eventLogFrame.origin.x, &eventLogFrame.origin.y,
		&eventLogFrame.size.width, &eventLogFrame.size.height);

	// Read the Notepad window's frame size 
	str = NXGetDefaultValue(PROGNAME, DEFAULTNOTEPADFRAME);
	sscanf(str, "x%fy%fw%fh%f",  &notepadFrame.origin.x,
		&notepadFrame.origin.y, &notepadFrame.size.width,
		&notepadFrame.size.height);

	// Read the Today window's frame size 
	str = NXGetDefaultValue(PROGNAME, DEFAULTTODAYFRAME);
	sscanf(str, "x%fy%fw%fh%f",  &todayFrame.origin.x,
		&todayFrame.origin.y, &todayFrame.size.width,
		&todayFrame.size.height);

	// Read the Week window's frame size 
	str = NXGetDefaultValue(PROGNAME, DEFAULTWEEKFRAME);
	sscanf(str, "x%fy%fw%fh%f",  &weekFrame.origin.x,
		&weekFrame.origin.y, &weekFrame.size.width,
		&weekFrame.size.height);

	// Read the sound default and process that.
	strcpy(alarmSound, NXGetDefaultValue(PROGNAME, DEFAULTALARMSOUND));
	
	// Read the fontName default and process that.
	strcpy(fontName, NXGetDefaultValue(PROGNAME, DEFAULTFONTNAME));

	// Read the ScreenSaver default and process that.
	strcpy(screenSaver, NXGetDefaultValue(PROGNAME, DEFAULTSCREENSAVER));
	
	fontSize = 	atof( NXGetDefaultValue(PROGNAME, DEFAULTFONTSIZE));
	lowPriority = 	atoi(NXGetDefaultValue(PROGNAME, DEFAULTLOWPRIORITY));
	highPriority = 	atoi( NXGetDefaultValue(PROGNAME,DEFAULTHIGHPRIORITY));
	clockType = 	atoi( NXGetDefaultValue(PROGNAME,DEFAULTCLOCKTYPE));
	alarmVolume = 	atof( NXGetDefaultValue(PROGNAME, DEFAULTALARMVOLUME));
	clockBitmapNumber = 	atoi(NXGetDefaultValue(PROGNAME, 
					DEFAULTCLOCKFACENUMBER));
							
	#ifdef DEBUG
		fprintf(stderr,"Global defaults read.\n");
		fprintf(stderr,	
			"Directory = <%s>\n"
			"Alarm = %s, PlayAlarm = %s\n"
			"alarmVolume = %f CompressEvents = %s\n"
			"lowPriority = %d. highPriority = %d Guru = %s\n"
			"ShowSeconds = %s, TodayShowTime = %s\n"
			"ShowDate = %s, overviewOnLaunch = %s\n"
			"ClockType = %d,\n"
			"notepadOnLaunch = %s, eventLogOnLaunch = %s\n"
			"todayOnLaunch = %s, hideOnLaunch = %s\n"
			"alarmVolume = %1.3f\n"
			"FontName = <%s>, FontSize = %3.1f\n"
			"ClockBitmapNumber=%d, militaryTime = %s.\n"
			"Overview:  x %.1f, y %.1f, w %.1f, h %.1f.\n"
			"EventLog:  x %.1f, y %.1f, w %.1f, h %.1f.\n"
			"Notepad:   x %.1f, y %.1f, w %.1f, h %.1f.\n"
			"Today:     x %.1f, y %.1f, w %.1f, h %.1f.\n\n",
			directory,
			alarmSound, playAlarm?"Yes":"No",
			alarmVolume, compressEvents?"Yes":"No",
			lowPriority, highPriority, guru?"Yes":"No",
			showSeconds?"Yes":"No", todayShowTime?"Yes":"No", 
			showDate?"Yes":"No",overviewOnLaunch?"Yes":"No",
			clockType,
			notepadOnLaunch?"Yes":"No", 
			eventLogOnLaunch?"Yes":"No",
			todayOnLaunch?"Yes":"No", hideOnLaunch?"Yes":"No",
			alarmVolume,
			fontName, fontSize,
			clockBitmapNumber, militaryTime?"Yes":"No",
			overviewFrame.origin.x, overviewFrame.origin.y,
			overviewFrame.size.width, overviewFrame.size.height,			
			eventLogFrame.origin.x, eventLogFrame.origin.y,
			eventLogFrame.size.width, eventLogFrame.size.height,									
			notepadFrame.origin.x, notepadFrame.origin.y,
			notepadFrame.size.width, notepadFrame.size.height,									
			todayFrame.origin.x, todayFrame.origin.y,
			todayFrame.size.width, todayFrame.size.height
			);
	#endif
    	return self;
}

- display:sender
{
	[self load: self];
	
	[alarmSoundForm		setStringValue: alarmSound	at:0];
	[alarmSoundButton	setState:	playAlarm];
	[alarmSoundForm		setEnabled:	playAlarm];
	[playButton		setEnabled:	playAlarm];
	[setButton		setEnabled:	playAlarm];
	[stopButton		setEnabled:	FALSE];
	
	[screenSaverButton	setState:	saveScreen];
	[setScreenSaverButton	setEnabled:	saveScreen];
	[testScreenSaverButton	setEnabled:	saveScreen];
	[screenSaverForm	setEnabled:	saveScreen];
	[screenSaverForm	setStringValue:	screenSaver at:0];
	
	[compressEventsButton	setState:	compressEvents];
	[hideOnLaunchButton	setState:	hideOnLaunch];
	[showSecondsButton	setState:	showSeconds];
	[showDateButton		setState:	showDate];
	[todayShowTimeButton	setState:	todayShowTime];
	[overviewOnLaunchButton	setState:	overviewOnLaunch];
	[notepadOnLaunchButton	setState:	notepadOnLaunch];
	[eventLogOnLaunchButton	setState:	eventLogOnLaunch];
	[sourceLoginOnLaunchButton setState:	sourceLoginOnLaunch];
	[todayOnLaunchButton	setState:	todayOnLaunch];
	[weekOnLaunchButton	setState:	weekOnLaunch];
	[militaryTimeButton	setState:	militaryTime];

	[clockFaceMatrix	selectCellWithTag:	clockBitmapNumber];
	[clockTypeButton	setState:		clockType];
	
	if( alarmVolume >= 0)
		{
		[volumeButton		setState:	TRUE];
		[volumeSlider		setEnabled:	TRUE];
		[volumeTextField	setStringValue: ""];
		[volumeSlider		setFloatValue:	
						(float) pow(10,alarmVolume)];
		}
	else
		{
		float volL, volR;
		
		[Sound getVolume: &volL: &volR];
		
		[volumeTextField	setStringValue: "System Volume"];
		[volumeSlider		setEnabled:	FALSE];
		[volumeSlider		setFloatValue:	
					(float) pow(10,((volL+volR)/2))];
		[volumeButton		setState:	FALSE];
		}
	
	[self 	makeKeyAndOrderFront:self];		
	[self setDocEdited: FALSE];
	return self;
}

- save			// For compatibility with TextWindow save method
{			// when called by Cassandra app

	[self	save: self];
	return self;
}

- save:sender
{
    	char string[20];
	BOOL changeQueue;

	changeQueue = FALSE;
	
	
	guru = [guruButton state];
	
	saveScreen		= [screenSaverButton state];
	strcpy(screenSaver,	[screenSaverForm stringValueAt: 0]);
	
	showSeconds 		= [showSecondsButton state];
	showDate 		= [showDateButton state];
	todayShowTime	 	= [todayShowTimeButton state];
	hideOnLaunch		= [hideOnLaunchButton		state];
	overviewOnLaunch 	= [overviewOnLaunchButton 	state];
	notepadOnLaunch 	= [notepadOnLaunchButton 	state];
	eventLogOnLaunch 	= [eventLogOnLaunchButton	state];
	sourceLoginOnLaunch	= [sourceLoginOnLaunchButton	state];
	todayOnLaunch 		= [todayOnLaunchButton		state];
	weekOnLaunch 		= [weekOnLaunchButton		state];
	playAlarm		= [alarmSoundButton		state];
	compressEvents		= [compressEventsButton		state];
	militaryTime 		= [militaryTimeButton state];
	clockType		= [clockTypeButton 		state];
	
	strcpy(alarmSound , (char *) [alarmSoundForm stringValueAt:0]);
	alarmVolume	= 	([volumeButton		state]?
				 (log10([volumeSlider		floatValue])):
				-1.0);		
	
	clockBitmapNumber = [clockFaceMatrix selectedTag];
			
    	[cassandra defaultsDidChange:self];
	[self	saveWindowPositions: self];
	
    	NXWriteDefault(PROGNAME,DEFAULTALARMSOUND, alarmSound);		
	NXWriteDefault(PROGNAME,DEFAULTSHOWSECONDS,(showSeconds?"Yes":"No"));
	NXWriteDefault(PROGNAME,DEFAULTSAVESCREEN,(saveScreen?"Yes":"No"));
	NXWriteDefault(PROGNAME,DEFAULTSHOWDATE,(showDate ? "Yes" : "No"));
	NXWriteDefault(PROGNAME,DEFAULTTODAYSHOWTIME,
		(todayShowTime ? "Yes" : "No"));
	NXWriteDefault(PROGNAME,DEFAULTPLAYALARM, (playAlarm ? "Yes" : "No"));
	NXWriteDefault(PROGNAME,DEFAULTCOMPRESSEVENTS,
		(compressEvents?"Yes":"No"));
				
	NXWriteDefault(PROGNAME,DEFAULTFONTNAME, fontName);
	sprintf(string,"%3.1f",fontSize);
	NXWriteDefault (PROGNAME, DEFAULTFONTSIZE,  string);


	NXWriteDefault(PROGNAME, DEFAULTEVENTLOGONLAUNCH,
		(eventLogOnLaunch ? "Yes" : "No"));
	NXWriteDefault(PROGNAME, DEFAULTHIDEONLAUNCH,
		(hideOnLaunch ? "Yes" : "No"));
	NXWriteDefault(PROGNAME,DEFAULTNOTEPADONLAUNCH,
		(notepadOnLaunch ?"Yes":"No"));
	NXWriteDefault(PROGNAME, DEFAULTOVERVIEWONLAUNCH,
		(overviewOnLaunch ? "Yes" : "No"));			
	NXWriteDefault(PROGNAME, DEFAULTSOURCELOGINONLAUNCH,
		(sourceLoginOnLaunch ? "Yes" : "No"));
	NXWriteDefault(PROGNAME, DEFAULTTODAYONLAUNCH,
		(todayOnLaunch ? "Yes" : "No"));
	NXWriteDefault(PROGNAME, DEFAULTWEEKONLAUNCH,
		(weekOnLaunch ? "Yes" : "No"));


	NXWriteDefault(PROGNAME,DEFAULTMILITARYTIME,(militaryTime?"Yes":"No"));

	sprintf(string,"%d",clockType);
	NXWriteDefault (PROGNAME, DEFAULTCLOCKTYPE, string);

	sprintf(string,"%f",alarmVolume);
	NXWriteDefault (PROGNAME, DEFAULTALARMVOLUME, string);
    	sprintf (string, "%d", clockBitmapNumber);
	NXWriteDefault(PROGNAME, DEFAULTCLOCKFACENUMBER, string);	
	
	#ifdef DEBUG
		fprintf(stderr,"Global defaults written.\n");
		fprintf(stderr,	
			"Directory = <%s>\n"
			"Alarm = %s, playAlarm = %s.\n"
			"Guru = %s\n"
			"ShowSeconds = %s, todayShowTime = %s\n"
			"ShowDate = %s, clockType = %d\n"
			"overviewOnLaunch = %s, hideOnLaunch = %s\n"
			"notepadOnLaunch = %s, eventLogOnLaunch = %s\n"
			"sourceLoginOnLaunch = %s,\n"
			"FontName = <%s>, FontSize = %3.1f\n"
			"alarmVolume = %f\n"
			"ClockBitmapNumber=%d, militaryTime = %s.\n\n",
			eventFile,  
			alarmSound, 	playAlarm?"Yes":"No", 
			guru?"Yes":"No",
			showSeconds?"Yes":"No", todayShowTime?"Yes":"No",
			showDate?"Yes":"No", clockType,
			overviewOnLaunch?"Yes":"No", hideOnLaunch?"Yes":"No",
			notepadOnLaunch?"Yes":"No", 
			eventLogOnLaunch?"Yes":"No",
			sourceLoginOnLaunch?"Yes":"No",
			fontName, fontSize,
			alarmVolume,
			clockBitmapNumber, militaryTime?"Yes":"No");
	#endif

	[self setDocEdited: FALSE];
    	return self;
}

// Method:		- saveWindowPositions: sender
// Arguments:		id sender (ignored)
// Description:		Saves the current window positions into the
//			Defaults database.
// Return Value:	self
- saveWindowPositions: sender
{	
	#ifdef DEBUG
		fprintf(stderr, "[global saveWindowPositions:sender]\n");
	#endif
		
	[self	saveThisWindowPosition: DEFAULTOVERVIEWFRAME: overview];
	[self	saveThisWindowPosition: DEFAULTNOTEPADFRAME: notepad];
	[self	saveThisWindowPosition: DEFAULTEVENTLOGFRAME: eventLog];
	[self	saveThisWindowPosition: DEFAULTTODAYFRAME: today];
	[self	saveThisWindowPosition: DEFAULTWEEKFRAME: week];
	return self;
}

// Method:		- saveThisWindowPosition: (char *) defaultName :sender
// Arguments:		(char *) defaultName -> the place in the defaults
//						database to save it
//			(id) sender:	the sender window
// Description:		Saves the current window position of the sender
//			 into the Defaults database.
// Return Value:	self
- saveThisWindowPosition: (char *) defaultName : (id) window
{
    	char string[20];
	NXRect windowFrame;
	
	#ifdef DEBUG
		fprintf(stderr, "[global saveThisWindowPosition::]\n");
	#endif
		
	if( ! [window isKindOf:	 [Window class] ])
		{
		fprintf(stderr,"Global -> SaveThisWindowPosition ERROR:"
			"Sender isn't of Window class. Contact Jiro.\n");
		return self;
		}
			
	if( [window isVisible])
		{
		[window getFrame: &windowFrame];
   		sprintf (string, "x%.0fy%.0fw%.0fh%.0f",
			windowFrame.origin.x, windowFrame.origin.y,
			windowFrame.size.width, windowFrame.size.height);
		NXWriteDefault(PROGNAME, defaultName, string);	
		#ifdef DEBUG
			fprintf(stderr,"defaultName %s: %s\n",
				defaultName,string);
		#endif
		}
	return self;
}


// Method:		- guru: sender
// Arguments:		id sender (ignored)
// Description:		Called when the user hits the guru button in
//			Preferences window. Verifies that they want to do it.
//
- guru : sender
{
	/* If the guru button has been turned on */
	if(  [guruButton state] == TRUE)
		if( NXRunAlertPanel(NULL,"The Guru Editor is very dangerous. Are you sure you want to turn it on?","NO","Yes",NULL) == 1)
			[guruButton setState: FALSE];
	
	[self windowChanged: self];
	return self;
}

- windowChanged: sender
{
	[self setDocEdited: TRUE];
	return self;
}

- clockTypeChanged: sender
{
	[self windowChanged: self];
	clockType		= [clockTypeButton state];
	if( clockType == CLOCK_DIGITAL)
		[clockFaceMatrix setEnabled: FALSE];
	return self;
}

- close
{	
	#ifdef DEBUG
		fprintf(stderr,"Global window about to close. "
				"Checking save.\n");
	#endif
	
	if( [self isDocEdited] && [self isVisible])
		{			
		 if (NXRunAlertPanel("Preferences not saved",
		 		"You have made changes to this window. "
				"Do you want to save them?",
				"Save","Don't Save",NULL) == 1 )
			[self save: self];
		}
	[super close];
	return self;
}

- volumeButtonHit: sender
	{
	if( [volumeButton state])
		{
		float vol1, vol2;
		
		[Sound getVolume: &vol1: &vol2];
		
		[volumeSlider		setEnabled:	TRUE];
		[volumeTextField	setStringValue:	""];
		[volumeSlider		setFloatValue:	
			(float) pow(10,((vol1+vol2)/2))];
		}
	else
		{
		[volumeTextField	setStringValue: "System Volume"];
		[volumeSlider		setEnabled:	FALSE];
		}
	return self;
	}

- trackVolumeSlider: sender
	{
	alarmVolume =  log10([volumeSlider floatValue]);
	[volumeTextField	setStringValue: ""];	
	return self;
	}

- screenSaverChanged: sender		// screensaver activated/deact
{
	BOOL state = [screenSaverButton state];
	
	[screenSaverForm	setEnabled: state];
	[setScreenSaverButton	setEnabled: state];
	[testScreenSaverButton	setEnabled: state];
	[self windowChanged: self];
	return self;
}
	
	
- testScreenSaver: sender	// test screensaver
{
	static char command[128];
	
	sprintf(command, "%s&", [self screenSaver]);
	
	#ifdef DEBUG
		fprintf(stderr,"%s: System autodimmed w/ <%s>\n", 
			PROGNAME, [self screenSaver]);
		NXBeep(); NXBeep();
	#endif
	
	system( command );
	return self;
}


- setScreenSaver: sender		// set screensaver
{
	OpenPanel *myOpenPanel;
	char tempDir[128], *tempFile;

	myOpenPanel = [OpenPanel new];
	
	if( index(screenSaver, '/') == (char *) 0)	// If the present isn't
		strcpy( screenSaver, SCREENSAVER);	// a path to a ss
		
	strcpy(tempDir, screenSaver);
	tempFile = rindex(tempDir,'/') + 1;
	*(rindex (tempDir,'/')) = '\0';
	

	#ifdef DEBUG
		fprintf(stderr,"Open directory <%s> with file <%s>\n", 
			tempDir, tempFile);
	#endif
	
	if( [myOpenPanel	runModalForDirectory:	tempDir
		file:	tempFile types: NULL]  == 0)
			return self;
	strcpy( screenSaver, [myOpenPanel filename]);
	[screenSaverForm	setStringValue:	screenSaver	at: 0];
	return self;
}




- checkScreenSaver: sender;		// see if valid screensaver
{
	if(  access( [screenSaverForm stringValueAt:0], R_OK) == -1)
		{
		NXRunAlertPanel("ScreenSaver not found",
			"I couldn't find a file at that path. "
				"Please double check.",
			 "OK",NULL,NULL);
		[screenSaverForm	selectText:self];
		}
	[self windowChanged: self];
	return self;
}



- sound: sender
	{
	if( [alarmSoundButton state])
		{
		[alarmSoundForm	setEnabled:	TRUE];
		[playButton	setEnabled:	TRUE];
		[setButton	setEnabled:	TRUE];
		}
	else
		{
		[alarmSoundForm	setEnabled:	FALSE];
		[playButton	setEnabled:	FALSE];
		[setButton	setEnabled:	FALSE];
		}
	return self;
	}


- playSound:sender
	{
	int error;
	
		
	if( index((char *)[alarmSoundForm stringValueAt:0], '/')==(char *)0)
		soundfile = [Sound findSoundFor:  
			(char *) [alarmSoundForm stringValueAt:0]];
	else
		soundfile = [Sound newFromSoundfile: 
			(char *) [alarmSoundForm stringValueAt:0]];
		
	if( soundfile != nil)
			{
			[soundfile setDelegate: self];
			// From 1.0 Docs, Sound Kit, pp22-498
			[Sound getVolume: &oldVolumeLeft:&oldVolumeRight];
			if( [self volume] >= 0)
				[Sound setVolume: [self volume]
						: [self volume]];

			error = [soundfile play];
			if( error == 0)		// No error
				{
				[stopButton 	setEnabled	: TRUE];
				[playButton 	setEnabled	: TRUE];
				 }
			else
				{
				char errorString[200];
				
				// Restore old volume
				[Sound	setVolume: oldVolumeLeft: 
						oldVolumeRight];

				sprintf(errorString,
					"Error #%d (%s) occured while "
					"trying to play the sound <%s>.\n", 
					error, SNDSoundError(error),
					[alarmSoundForm stringValueAt:0]);
					
				NXRunAlertPanel("Alarm Error",errorString, 
						"Oh well...",NULL,NULL);
				}
			}
		else
			{
			NXRunAlertPanel("Sound not found",
				"I couldn't find that sound.", 
				"Oh well...",NULL,NULL);
			[alarmSoundForm	selectText:self];
			}
	
	return self;
	}

- checkSound:sender
	{
	if(  	([Sound findSoundFor:  
			(char *) [alarmSoundForm stringValueAt:0]] == nil)  ||
		( access( [alarmSoundForm stringValueAt:0], R_OK) == -1))
		{
		NXRunAlertPanel("Sound not found",
			"I couldn't find that sound. Please double check.",
			 "OK",NULL,NULL);
		[alarmSoundForm	selectText:self];
		}
	return self;
	}


- stopSound:sender
	{
	[soundfile stop];
   	return self;
	}

- setSound: sender
	{
	OpenPanel *myOpenPanel;
	char tempDir[128], *tempFile;

	myOpenPanel = [OpenPanel new];
	
	if( index(alarmSound, '/') == (char *) 0)	// If the present isn't
		strcpy( alarmSound,ALARMSOUND);		// a path to a sound
		
	strcpy(tempDir, alarmSound);
	tempFile = rindex(tempDir,'/') + 1;
	*(rindex (tempDir,'/')) = '\0';
	

	#ifdef DEBUG
		fprintf(stderr,"Open directory <%s> with file <%s>\n", 
			tempDir, tempFile);
	#endif
	
	if( [myOpenPanel	runModalForDirectory:	tempDir
		file:	tempFile types:  alarmExtensions]  == 0)
			return self;
	strcpy( alarmSound, [myOpenPanel filename]);
	[alarmSoundForm	setStringValue:	alarmSound	at: 0];
	return self;
	}

- willPlay : sender
	{
	#ifdef DEBUG
		fprintf(stderr,"Alarm sound starting with volume %f.\n",
		[self volume]);
	#endif
	
	[playButton setEnabled: FALSE];
	return self;
	}

- hadError : sender
	{
	char errorString[200];
	int error = [[sender soundBeingProcessed] processingError];	
	
	sprintf(errorString,
		"Error #%d (%s) occured while playing the sound <%s>.\n", 
		error, SNDSoundError(error),
		[alarmSoundForm stringValueAt:0]);
					
	NXRunAlertPanel("Alarm Error",errorString, 
			"Oh well...",NULL,NULL);
		
	[stopButton setEnabled: FALSE];
	
	if( [alarmSoundButton state])
		[playButton	setEnabled:	TRUE];
	else
		[playButton	setEnabled:	FALSE];
		
	// Restore old volume
	[Sound	setVolume: oldVolumeLeft: oldVolumeRight];
	return self;
	}

- didPlay:sender
	{
	[soundfile free];
	[stopButton setEnabled: FALSE];
		
	if( [alarmSoundButton state])
		[playButton	setEnabled:	TRUE];
	else
		[playButton	setEnabled:	FALSE];

	// Restore old volume
	[Sound	setVolume: oldVolumeLeft: oldVolumeRight];
	 return self; 
	 }
	 
	 
- (int) lowPriority		{ return lowPriority; }
- (int) highPriority		{ return highPriority; }
- (int) clockType		{ return clockType; }

- (float) volume		{ return alarmVolume; }
- (double) fontSize		{ return fontSize; }
	
- (const char *) alarmSound	{ return alarmSound; }
- (const char *) eventFile	{ return eventFile; }
- (const char *) eventLogFile	{ return eventLogFile; }
- (const char *) notepadFile	{ return notepadFile; }
- (const char *) fontName 	{ return fontName; }
- (const char *) screenSaver	{ return screenSaver; }
- (const char *) sourceLoginFile	{ return sourceLoginFile; }
- (const char *) sourceLogoutFile	{ return sourceLogoutFile; }
	
- (BOOL) autoLaunched		{ return autoLaunched; }
- (BOOL) compressEvents		{ return compressEvents; }
- (BOOL) eventLogOnLaunch	{ return eventLogOnLaunch; }
- (BOOL) guru			{ return guru; }
- (BOOL) hideOnLaunch		{ return hideOnLaunch; }
- (BOOL) notepadOnLaunch	{ return notepadOnLaunch; }
- (BOOL) overviewOnLaunch	{ return overviewOnLaunch; }
- (BOOL) playAlarm		{ return playAlarm; }
- (BOOL) saveScreen		{ return saveScreen; }
- (BOOL) showSeconds		{ return showSeconds; }
- (BOOL) showDate		{ return showDate;}
- (BOOL) sourceLoginOnLaunch	{ return sourceLoginOnLaunch; }
- (BOOL) todayOnLaunch		{ return todayOnLaunch; }
- (BOOL) todayShowTime		{ return todayShowTime; }
- (BOOL) militaryTime		{ return militaryTime; }
- (BOOL) weekOnLaunch		{ return weekOnLaunch; }

- (NXRect *) overviewFrame	{ return &overviewFrame; }
- (NXRect *) eventLogFrame	{ return &eventLogFrame; }
- (NXRect *) notepadFrame	{ return &notepadFrame; }
- (NXRect *) todayFrame		{ return &todayFrame; }
- (NXRect *) weekFrame 		{ return &weekFrame; }

- (const char *) clockfaceBitmapName
	{
	static char     bitmapName[30];
	sprintf(bitmapName, "%s%d", BITMAPNAME, clockBitmapNumber);
	return bitmapName;
	}
@end
